package com.hjy.cabinet.ws.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.hjy.cabinet.ws.config.AnnotationScanner;
import com.hjy.cabinet.ws.domain.ws.InfoBackEvent;
import com.hjy.cabinet.ws.domain.ws.WbsocketResponseBody;
import com.hjy.cabinet.ws.domain.ws.WebSocketRequest;
import com.hjy.cabinet.ws.domain.ws.WsClassData;
import com.hjy.cabinet.ws.domain.ws.WsData;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class WebSocketDataHander {

    ExecutorService executorService = Executors.newFixedThreadPool(20);

    private static WebSocketDataHander instance;


    private WebSocketDataHander() {
    }

    public static WebSocketDataHander getInstance() {
        if (instance == null) {
            synchronized (WebSocketDataHander.class) {
                if (instance == null) {
                    instance = new WebSocketDataHander();
                }
            }
        }
        return instance;
    }


    public void textDeal(String text){

        System.out.println("接收到消息: " + text);
        if (text == null) {
            return;
        }
        String[] split = text.split("-");
        //这是接收到的数据 1表示收到的请求消息
        if (split[0].equals("send") && (split.length > 1)) {

            String message = split[1];
            // 显示接收到的消息
            ObjectMapper objectMapper = new ObjectMapper();
            WebSocketRequest webSocketRequest;
            try {
                webSocketRequest = objectMapper.readValue(message, WebSocketRequest.class);
                Object[] params = webSocketRequest.getArgs();  // 获取参数数组
                Map<String, WsClassData> classesResult = AnnotationScanner.getClassesResult();
                for (String methodName : classesResult.keySet()) {
                    if (methodName.equals(webSocketRequest.getMethodName())) {
                        WsClassData wsClassData = classesResult.get(methodName);
                        Class<?> clazz = wsClassData.getClazz();
                        Constructor<?> constructor = clazz.getConstructor();
                        // 创建 UserDatabase 实例
                        Object instance = constructor.newInstance();
                        //处理方法的请求类型
                        Class<?>[] parameterTypes = wsClassData.getMethod().getParameterTypes();
                        Method method = clazz.getDeclaredMethod(webSocketRequest.getMethodName(), parameterTypes);
                        method.setAccessible(true);
                        Object[] args = new Object[parameterTypes.length];
                        if (parameterTypes.length == params.length) {
                            // 检查每个参数类型
                            for (int i = 0; i < parameterTypes.length; i++) {
                                Class<?> parameterType = parameterTypes[i];
                                Object o = convertJsonToObject(params[i].toString(), parameterType);
                                args[i] = o;
                            }
                        }
                        executorService.submit(() -> {
                            try {
                                //方法返回的结果值
                                Object invoke = method.invoke(instance, args);
                                System.out.println(invoke);
                                if (invoke == null) {
                                    invoke = "操作成功";
                                }
                                String connId = webSocketRequest.getConnId();
                                if (null != connId) {
                                    WbsocketResponseBody success = WbsocketResponseBody.success(invoke);
                                    success.setClientIp(webSocketRequest.getClientIp());
                                    success.setMethodName(webSocketRequest.getMethodName());
                                    success.setConnId(connId);
                                    WebsocketService websocketService = WebsocketService.getInstance();
                                    websocketService.backMessage(success);
                                }

                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                                Throwable targetException = e.getTargetException();
                                WbsocketResponseBody wbsocketResponseBody = new WbsocketResponseBody();
                                if (targetException instanceof RuntimeException) {
                                    RuntimeException runtimeException = (RuntimeException) targetException;
                                    wbsocketResponseBody.setMsg("failed");
                                    wbsocketResponseBody.setMsg(runtimeException.getMessage());
                                } else {
                                    wbsocketResponseBody.setMsg("failed");
                                    wbsocketResponseBody.setMsg("内部错误");
                                }
                                wbsocketResponseBody.setClientIp(webSocketRequest.getClientIp());
                                wbsocketResponseBody.setConnId(webSocketRequest.getConnId());
                                WebsocketService websocketService = WebsocketService.getInstance();
                                websocketService. backMessage(wbsocketResponseBody);
                            } catch (IllegalAccessException e) {
                                WbsocketResponseBody wbsocketResponseBody = new WbsocketResponseBody();
                                wbsocketResponseBody.setMsg("failed");
                                wbsocketResponseBody.setMsg("内部错误");
                                wbsocketResponseBody.setClientIp(webSocketRequest.getClientIp());
                                wbsocketResponseBody.setConnId(webSocketRequest.getConnId());
                                WebsocketService websocketService = WebsocketService.getInstance();
                                websocketService. backMessage(wbsocketResponseBody);
                                throw new RuntimeException(e);
                            }
                        });


                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
            //2 表示收到的回复的数据
        } else if (split[0].equals("receive") && (split.length > 1)) {
            //处理返回的数据
            String message = split[1];
            ObjectMapper objectMapper = new ObjectMapper();
            String connId = null;
            try {
                WbsocketResponseBody wbsocketResponseBody = objectMapper.readValue(message, WbsocketResponseBody.class);
                connId = wbsocketResponseBody.getConnId();
                WebsocketService websocketService = WebsocketService.getInstance();
                InfoBackEvent infoBack = websocketService.getInfoMap().get(connId);
                if (infoBack != null) {
                    infoBack.back(wbsocketResponseBody);
                }

            } catch (JsonProcessingException e) {

                throw new RuntimeException(e);

            } finally {
                //删除掉已经返回的方法的回调，防止重复触发
                if (connId != null) {
                    WebsocketService websocketService = WebsocketService.getInstance();
                    websocketService.getInfoMap().remove(connId);
                }


            }
        }
    }




    public <T> T convertJsonToObject(String json, Class<T> parameterType) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.readValue(json, parameterType);
    }


}
